package com.k8s.service.impl;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ArrayUtil;
import com.k8s.config.AutoRefreshConfig;
import com.k8s.domain.K8sProperties;
import com.k8s.domain.MessageSendProperties;
import com.k8s.enums.MessageEnum;
import com.k8s.messages.MessageService;
import com.k8s.service.MonitorK8sService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;

@Service
public class MonitorK8sServiceImpl implements MonitorK8sService {
    private final static Logger LOGGER = LoggerFactory.getLogger(MonitorK8sServiceImpl.class);
    private static MessageSendProperties messageSendProperties = new MessageSendProperties(600, System.currentTimeMillis() / 1000);
    private static final String READY = "ready";
    private static final String READY_CHECK_STR = "0";
    private static final String RESTARTS = "restarts";
    private static final String AGE = "age";
    private static final String SIGN_DH = ",";
    private static final String SIGN_MH = ":";
    private static List<K8sProperties> POD_THRES_HOLD_LIST = new ArrayList<>();
    @Resource
    private AutoRefreshConfig config;

    @Resource
    private MessageService messageService;

    @Scheduled(cron = "${k8s.cron}")
    public void autoAnalysis() {
        System.out.println("定时器开始解析");
        analysis(null, null, null);
    }

    @Override
    public Map analysis(String monitorK8s, HttpServletRequest request, String stay) {
        Map<String, Object> resultMap = new HashMap();
        Boolean resultReturn = false;
        if (!StringUtils.isEmpty(monitorK8s)) {
            resultReturn = true;
        }
        if (!StringUtils.isEmpty(stay)) {
            messageSendProperties.setSendMessageTime(Integer.valueOf(stay));
        }
        if (config.getEnableAnalysis()) {
            System.out.println("开始解析");
            return execCommand(resultReturn);
        }
        return resultMap;
    }

    /**
     * 执行命令
     * config.getSoftType(): 1:k8s 2:docker
     *
     * @param resultReturn true: 接口调用 false: 定时器调用
     */
    private Map execCommand(Boolean resultReturn) {
        Map m = new HashMap();
        switch (config.getSoftType()) {
            case 1:
                String namespace = config.getNamespace();
                if (namespace.contains(",")) {
                    String[] namespaceArr = namespace.split(",");
                    for (String name : namespaceArr) {
                        m = k8sPodStartState(resultReturn, name, m);
                    }
                    break;
                }
                m = k8sPodStartState(resultReturn, namespace, null);
                break;
            case 2:
//                dockerAnalysis();
                break;
            default:
                break;
        }
        return m;
    }

    /**
     * 解析k8s命令
     */
    private Map k8sPodStartState(Boolean resultReturn, String namespace, Map map) {
        List<K8sProperties> podList = new ArrayList<>();
        List<K8sProperties> errPodList = new ArrayList<>();
        List<String> specifyPodList = new ArrayList<>();
        Map<String, Integer> podThresholdMap = new HashMap<>();
        List<K8sProperties> podThresholdList = new ArrayList<>();
        Map<String, Object> resultMap = new HashMap<>();
        if (MapUtil.isNotEmpty(map)) {
            resultMap = map;
        }
        // 设置指定pod的阈值
        if (!StringUtils.isEmpty(config.getPerPodThreshold())) {
            String[] split = config.getPerPodThreshold().split(SIGN_DH);
            for (String podName : split) {
                if (podName.contains(SIGN_MH)) {
                    String[] podThreshold = podName.split(SIGN_MH);
                    podThresholdMap.put(podThreshold[0], Integer.valueOf(podThreshold[1]));
                    continue;
                }
                podThresholdMap.put(podName, config.getGlobalPodThreshold());
            }
        }

        // 设置统计指定pod的预警
        if (!StringUtils.isEmpty(config.getPodNames())) {
            String[] split = config.getPodNames().split(SIGN_DH);
            for (String podName : split) {
                specifyPodList.add(podName);
            }
        }
        //执行命令
        try {
            // 查看全部pod
            String command = "kubectl get pods -n " + namespace;
            if (!StringUtils.isEmpty(config.getCommand())) {
                command = config.getCommand();
            }
            System.out.println(command);
            Process process = Runtime.getRuntime().exec(command);

            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line, ready, age;
            Integer readyLocation = 0, restarts, restartsLocation = 0, ageLocation = 0;
            Boolean firstLine = true;
            while ((line = reader.readLine()) != null) {
                String[] splitStr = line.split("\\s+");
                splitStr = ArrayUtil.removeBlank(splitStr);
                if (firstLine) {
                    for (int i = 0; i < splitStr.length; i++) {
                        if (READY.equalsIgnoreCase(splitStr[i].trim())) {
                            readyLocation = i;
                        } else if (RESTARTS.equalsIgnoreCase(splitStr[i].trim())) {
                            restartsLocation = i;
                        } else if (AGE.equalsIgnoreCase(splitStr[i].trim())) {
                            ageLocation = i;
                        }
                    }
                    firstLine = false;
                    continue;
                }
                if (!CollectionUtils.isEmpty(specifyPodList)) {
                    boolean specifyPod = false;
                    for (String podName : specifyPodList) {
                        if (splitStr[0].contains(podName)) {
                            specifyPod = true;
                        }
                    }
                    if (!specifyPod) {
                        continue;
                    }
                }
                // 开始遍历pod
                ready = splitStr[readyLocation];
                restarts = Integer.valueOf(splitStr[restartsLocation]);
                age = splitStr[ageLocation];
                K8sProperties k8sProperties = new K8sProperties();
                k8sProperties.setPodName(splitStr[0]);
                k8sProperties.setReady(ready);
                k8sProperties.setNamespace(namespace);
                k8sProperties.setRestarts(restarts);
                k8sProperties.setAge(age);

                // 所有pod
                podList.add(k8sProperties);

                // 有问题的pod
                if (ready.contains(READY_CHECK_STR)) {
                    errPodList.add(k8sProperties);
                    // 预警发短信
                    Boolean configPod = false;
                    if (MapUtil.isNotEmpty(podThresholdMap)) {
                        for (Map.Entry<String, Integer> pod : podThresholdMap.entrySet()) {
                            if (splitStr[0].contains(pod.getKey())) {
                                configPod = true;
                                Integer timers = pod.getValue();
                                if (k8sProperties.getRestarts().compareTo(timers) == 1) {
                                    podThresholdList.add(k8sProperties);
                                }
                                continue;
                            }
                        }
                    }
                    // 未配置pod的预警限制数量比较设置全局阈值
                    if (!configPod) {
                        if (k8sProperties.getRestarts().compareTo(config.getGlobalPodThreshold()) == 1) {
                            podThresholdList.add(k8sProperties);
                        }
                    }
                }
            }

            reader.close();
            process.waitFor();

            // 发送短信、
            if (!CollectionUtils.isEmpty(podThresholdList)) {
                if (!CollectionUtils.isEmpty(POD_THRES_HOLD_LIST)) {
                    POD_THRES_HOLD_LIST.clear();
                    POD_THRES_HOLD_LIST.addAll(podThresholdList);
                }

                if (messageSendProperties.getSendMessageTime().compareTo(config.getSendMessageTime()) == 0) {
                    if (messageSendProperties.getSendDate().compareTo(System.currentTimeMillis() / 1000) != 1) {
                        // 发送短信给指定用户
                        try {
                            sendMessage(podThresholdList);
                        } catch (Exception e) {
                            System.out.println("发送短信给指定用户：" + e.getMessage());
                            LOGGER.info("发送短信给指定用户：{}", e.getMessage());
                        }
                        // 重新赋值当前时间
                        messageSendProperties.setSendDate(System.currentTimeMillis() / 1000 + messageSendProperties.getSendMessageTime());

                    }
                } else {
                    // 发送短信给指定用户
                    try {
                        sendMessage(podThresholdList);
                    } catch (Exception e) {
                        System.out.println("修改发送短信时间将立即发送短信给指定用户：" + e.getMessage());
                        LOGGER.info("修改发送短信时间将立即发送短信给指定用户：{}", e.getMessage());
                    }
                    messageSendProperties.setSendDate(System.currentTimeMillis() / 1000 + config.getSendMessageTime());
                    messageSendProperties.setSendMessageTime(config.getSendMessageTime());

                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        if (resultReturn) {
            resultMap.put("podTotalList", podList);
            resultMap.put("errPodList", errPodList);
            resultMap.put("podThresholdList", podThresholdList);
        }
        return resultMap;
    }

    /**
     * 发送短信
     *
     * @param podThresholdList 预警pod列表数据
     */
    private void sendMessage(List<K8sProperties> podThresholdList) {
        String[] receiverArr = null;
        // 判断选择邮件，主题不能为空
        if (!StringUtils.isEmpty(config.getMode()) && MessageEnum.EMAIL.getMessage().equalsIgnoreCase(config.getMode())) {
            if (StringUtils.isEmpty(config.getSubject())) {
                LOGGER.info("sendMessage发送邮件失败，邮件主题不能为空");
                return;
            }
        }
        // 获取接收人
        String mobile = config.getReceiver();
        if (!StringUtils.isEmpty(mobile)) {
            receiverArr = mobile.contains(SIGN_DH) ? mobile.split(SIGN_DH) : new String[]{mobile};
        }

        if (ArrayUtil.isNotEmpty(receiverArr)) {
            for (String receiver : receiverArr) {
                // 调用发送短信接口
                messageService.sendMessage(20L, receiver,  podThresholdList.toString() +"【水中游】" , "GDT_SZY");
            }
        }
    }

    @Override
    public List<K8sProperties> selectPodList() {
        return POD_THRES_HOLD_LIST;
    }


}
